package com.perfma.xtest.file;

import java.io.*;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.zip.ZipEntry;
import java.util.zip.ZipInputStream;

/**
 *
 *
 * @author: junhui.si
 * @date: 2024-07-15 18:17
 **/
public class Zip {
    public static void main(String[] args) throws IOException {
        String zipFilePath = "/Users/sijunhui/Downloads/log/zy.zip"; // ZIP文件路径
        String destDir = "/Users/sijunhui/Downloads/log"; // 解压目标目录
        unzip(zipFilePath, destDir);
    }

    /**
     * 解压ZIP文件到指定目录
     *
     * @param zipFilePath ZIP文件路径
     * @param destDir     解压目标目录
     * @throws IOException 如果发生I/O错误
     */
    public static void unzip(String zipFilePath, String destDir) throws IOException {
        File destDirFile = new File(destDir);
        if (!destDirFile.exists()) {
            destDirFile.mkdirs();
        }

        ZipInputStream zipIn = new ZipInputStream(Files.newInputStream(Paths.get(zipFilePath)));
        ZipEntry entry = zipIn.getNextEntry();

        // 遍历ZIP文件中的每个条目
        while (entry != null) {
            String filePath = destDir + File.separator + entry.getName();
            if (entry.getName().startsWith("__MACOSX/")) {
                // 跳过以 __MACOSX/ 开头的条目
                System.out.println("Skipping entry: " + entry.getName());
            } else {
                if (!entry.isDirectory()) {
                    // 如果条目不是目录，则提取文件
                    extractFile(zipIn, filePath);
                } else {
                    // 如果条目是目录，则创建目录
                    File dir = new File(filePath);
                    dir.mkdirs();
                }
            }
            zipIn.closeEntry();
            entry = zipIn.getNextEntry();
        }
        zipIn.close();
    }

    /**
     * 从ZIP输入流中提取文件
     *
     * @param zipIn   ZIP输入流
     * @param filePath 文件保存路径
     * @throws IOException 如果发生I/O错误
     */
    private static void extractFile(ZipInputStream zipIn, String filePath) throws IOException {
        BufferedOutputStream bos = new BufferedOutputStream(Files.newOutputStream(Paths.get(filePath)));
        byte[] bytesIn = new byte[4096];
        int read = 0;

        // 读取ZIP条目中的数据并写入到文件中
        while ((read = zipIn.read(bytesIn)) != -1) {
            bos.write(bytesIn, 0, read);
        }

        bos.close();
    }
}
